package web.base.user.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import web.base.user.dao.UserDao;
import web.base.user.dict.UserState;
import web.base.user.exception.UserErrorCode;
import web.base.user.exception.UserException;
import web.base.user.model.UserEntity;
import web.common.core.collection.Page;
import web.common.core.security.PasswordEncoder;
import web.common.jdo.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Map;

/**
 * @author Jin Zheng
 * @since 2022-01-03
 */
@Service("baseUserService")
@Transactional
public class UserService {
	private static Logger logger = LoggerFactory.getLogger(UserService.class);

	private static final String MOBILE = "mobile";
	private UserDao userDao;
	private PasswordEncoder passwordEncoder;

	public UserService() {
	}

	public UserEntity register(UserEntity user) {
		user.setId(null);
		if (userDao.exist(user, MOBILE)) {
			throw new UserException(UserErrorCode.EXISTS, "手机号码");
		}

		var now = LocalDateTime.now();
		user.setPassword(passwordEncoder.encode(user.getPassword()));
		user.setState(UserState.ACTIVE);
		user.setRegisterTime(now);
		user.setLoginTime(now);
		userDao.save(user);
		return user;
	}

	public UserEntity login(UserEntity user) {
		UserEntity u = userDao.getObject(Map.of(MOBILE, user.getMobile()));
		if (u == null) {
			logger.warn("手机号码不存在: {}", user.getMobile());
			throw new UserException(UserErrorCode.LOGIN_FAILURE);
		}
		if (!passwordEncoder.matches(user.getPassword(), u.getPassword())) {
			logger.warn("密码错误: {}", user.getPassword());
			throw new UserException(UserErrorCode.LOGIN_FAILURE);
		}
		if (u.getState() != UserState.ACTIVE) {
			logger.warn("用户状态: {}", u.getState());
			throw new UserException(UserErrorCode.LOGIN_FAILURE);
		}

		UserEntity u2 = new UserEntity();
		u2.setId(u.getId());
		u2.setLoginTime(LocalDateTime.now());
		userDao.update(u2);
		return u;
	}

	public UserEntity get(Integer id) {
		return userDao.get(id);
	}

	public Page list(UserEntity param, Page page) {
		return userDao.listPage(param, page);
	}

	@Autowired
	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}

	@Autowired
	public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
		this.passwordEncoder = passwordEncoder;
	}
}
